#ifndef __MULTICPU_H__
#define __MULTICPU_H__

typedef unsigned long   DWORD;
typedef unsigned short   WORD;
typedef unsigned char    BYTE;

extern DWORD mp_OldHandler;
extern WORD  mp_OldSelector;
extern BYTE  mp_OldFlag;
       
extern DWORD mp_NumOfCPUs;
extern DWORD mp_PCR_VA;
extern DWORD *mp_PCR_VA_array;

///////////////////////////////////////////////////////////////////
// mp_Init()
//
//  Initialize multicpu module
//
///////////////////////////////////////////////////////////////////
void mp_Init();


///////////////////////////////////////////////////////////////////
// mp_Done()
//
//  Unhook all hooks installed by multicpu module
//
///////////////////////////////////////////////////////////////////
//void mp_Done();


///////////////////////////////////////////////////////////////////
// mp_NMIHook()
//
//  My own NMI handler
//
///////////////////////////////////////////////////////////////////
//void mp_NMIHook();


///////////////////////////////////////////////////////////////////
// mp_AnalyzeHalInitProcessor()
//
//  Returns number of active CPUs in the system.
//    -  Sets mp_NumOfCPUs to the number of active processors in the
//       system.
//    -  Sets mp_PCR_VA_array to the value extracted from the HAL 
//       code.  
//
///////////////////////////////////////////////////////////////////
DWORD mp_AnalyzeHalInitProcessor();

///////////////////////////////////////////////////////////////////
// mp_GetLocalAPIC_ID()
//
//  Return local APIC ID for current processor.
//
///////////////////////////////////////////////////////////////////
//DWORD mp_GetLocalAPIC_ID();


///////////////////////////////////////////////////////////////////
// mp_ResumeSecondCPUs()
//
//  Resume all secondary processors.
//
///////////////////////////////////////////////////////////////////
//DWORD mp_ResumeSecondCPUs();


///////////////////////////////////////////////////////////////////
// mp_StopSecondCPUs()
//
//  Stop all secondary processors.
//
///////////////////////////////////////////////////////////////////
//DWORD mp_StopSecondCPUs();


///////////////////////////////////////////////////////////////////
// mp_INT02_IOAPIC()
//
//  Non-maskable interrupt hook.
//
///////////////////////////////////////////////////////////////////
//DWORD mp_INT02_IOAPIC();


///////////////////////////////////////////////////////////////////
// mp_HookIDTEntry()
//
//  Hook interrupt in given IDT.
//
// INPUT:
//         ; DL  = Int flags byte
//         ; EAX = vector to hook
//         ; ESI = pointer to IDTBase
//         ; EDI = new interrupt dispatcher virtual address
///////////////////////////////////////////////////////////////////
DWORD mp_HookIDTEntry();


///////////////////////////////////////////////////////////////////
// mp_HookInterrupt()
//
//  Hook interrupt on all processors in the system.
//
// INPUT:
//         ; DL  = Int flags byte
//         ; EAX = vector to hook
//         ; EDI = new interrupt dispatcher virtual address
///////////////////////////////////////////////////////////////////
DWORD mp_HookInterrupt(VOID);

///////////////////////////////////////////////////////////////////
// mp_GetIDTBase
//
//  Get IDT Base address
//
///////////////////////////////////////////////////////////////////
DWORD mp_GetIDTBase(DWORD IdtNum);

#endif
